#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pii std::pair<int,int>
#define mkp std::make_pair
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))

inline void smax(int &a, int b) {
	a = max(a, b);
}
inline void smin(int &a, int b) {
	a = min(a, b);
}

const int N = 1e5 + 7;
int n, m, L, V, t, f[N], p[N];

struct car {
	int d, v, a;
}c[N];

struct Segment {
	int l, r;
}seg[N];

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);

	freopen("detect.in", "r", stdin);
	freopen("detect.out", "w", stdout);

	std::cin >> t;
	for (int round = 1; round <= t; ++round) {
		std::cin >> n >> m >> L >> V;
		memset(f, 0, sizeof f);
		for (int i = 1; i <= n; ++i) {
			std::cin >> c[i].d >> c[i].v >> c[i].a;
		}
		for (int i = 1; i <= m; ++i) {
			std::cin >> p[i];
		} 
		std::sort(p + 1, p + 1 + m);
		/*for (int i = 1; i <= m; ++i) {
			std::cout << p[i] << ' ';
		}*/
		//std::cout << c[3].d;
		int cnt = 0;
		for (int i = 1; i <= n; ++i) {
			if (c[i].a < 0) {
				int pos = std::lower_bound(p + 1, p + 1 + m, c[i].d) - p;
				if (pos == m + 1) 
					continue;
				int s = p[pos] - c[i].d, v0 = c[i].v, a = c[i].a;
				double v1 = sqrt(v0 * v0 * 1.0 + 2.0 * a * s);
				if (ceil(v1) > V)
					++cnt, f[i] = 1;
			} else {
				int pos = m;
				int s = p[pos] - c[i].d, v0 = c[i].v, a = c[i].a;
				if (s < 0)
					continue;
				double v1 = sqrt(v0 * v0 * 1.0 + 2.0 * a * s);
				//std::cout << i << ' ' << pos << '\n';
				if (ceil(v1) > V)
					++cnt, f[i] = 1;
			}
		}
		int tot = 0;
		for (int i = 1; i <= n; ++i) if (f[i]) {
			int v1 = V, v0 = c[i].v, a = c[i].a;
			double tmps;
			if (a == 0)
				tmps = 0;
			else
				tmps = (v1 * v1 - v0 * v0) * 1.0 / 2.0 / a; 

			if (c[i].a < 0) {
				int s = ceil(tmps);
				int p1 = std::lower_bound(p + 1, p + 1 + m, c[i].d + s) - p;//check again!
				--p1;
				int pos = std::lower_bound(p + 1, p + 1 + m, c[i].d) - p;
				//std::cout << p1 << '\n';
				seg[++tot] = {pos, p1};
			} else {
				if (c[i].v > V) {
					int p1 = std::lower_bound(p + 1, p + 1 + m, c[i].d) - p;
					seg[++tot] = {p1, m};
					continue;
				}
				int s = floor(tmps);
				int p1 = std::upper_bound(p + 1, p + 1 + m, c[i].d + s) - p;//check again!
				seg[++tot] = {p1, m};
				
			}

			//std::cout << i << ": " << s << '\n';
		}
		std::sort(seg + 1, seg + 1 + tot, [&](Segment A, Segment B) { return A.l < B.l; });
		int r = seg[1].r, ans = 1;
		for (int i = 2; i <= tot; ++i) {
			if (seg[i].l > r) {
				r = seg[i].r;
				++ans;
			} else {
				smin(r, seg[i].r);
			}
		}
		if (tot == 0)
			ans = 0;
		std::cout << cnt << ' ' << m - ans << '\n';
		//for (int i = 1; i <= tot; ++i) {
		//	std::cout << seg[i].l << ' ' << seg[i].r << '\n';
		//}
	}

	return 0;
}